#tag Class
Protected Class sjgEZTwain
	#tag Method, Flags = &h0
		Sub Constructor()
		  Const thisModule = " - Constructor"
		  #If TargetWin32
		    Soft Declare Function TWAIN_IsAvailable Lib "EZTW32.dll" As Integer
		    Soft Declare Function TWAIN_EasyVersion Lib "EZTW32.dll" As Integer
		    Dim ret As Integer
		    If System.IsFunctionAvailable("TWAIN_IsAvailable","EZTW32.dll") Then
		      If TWAIN_IsAvailable = 1 Then
		        Self.Available = True
		        ret = TWAIN_EasyVersion
		        EZTwainVersion = Format(ret / 100,"0.00")
		      Else
		        reportError "TWAIN Source Manager cannot be loaded" + thisModule
		      End If
		    Else
		      reportError "Unable to access dll" + thisModule
		    End If
		  #Else
		    reportError "Available for Windows only" + thisModule
		  #EndIf
		  
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h0
		Function AcquireToFile(f As Folderitem = Nil) As Boolean
		  Dim retVal As Boolean
		  Const thisModule = "- AcquireToFile"
		  #If TargetWin32
		    If Self.Available Then
		      Soft Declare Function TWAIN_AcquireToFilename Lib "EZTW32.dll"(hwndApp As Integer, pszFile As CString) As Integer
		      Dim i As Integer
		      
		      If f <> Nil Then
		        fItem = f
		      Elseif fItem Is Nil Then
		        fItem = TemporaryFolder.Child("sjgeztwaintemp.bmp")
		      End If
		      If fItem <> Nil Then
		        i = TWAIN_AcquireToFilename(0,fItem.AbsolutePath)
		        If i = 0 Then
		          If fItem.Exists Then
		            pic = fItem.OpenAsPicture
		            If pic <> Nil Then
		              retVal = True
		            End If
		          Else
		            reportError "File not created" + thisModule
		          End If
		        Else
		          Select Case i
		          Case -1
		            reportError "Acquire failed OR user cancelled File Save dialog" + thisModule
		          Case -2
		            reportError "file open error (invalid path or name, or access denied)" + thisModule
		          Case -3
		            reportError "(weird) unable to lock DIB - probably an invalid handle" + thisModule
		          Case -4
		            reportError "writing BMP data failed, possibly output device is full" + thisModule
		          End Select
		        End If
		      Else
		        reportError "Nil FolderItem" + thisModule
		      End If
		      If retVal = False Then 
		        pic = Nil
		      End If
		    End If
		  #EndIf
		  Return retVal
		  
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function AcquireToClipboard() As Boolean
		  Dim retVal As Boolean
		  Const thisModule = "- AcquireToClipboard"
		  #If TargetWin32
		    If Self.Available Then
		      Soft Declare Function TWAIN_AcquireToClipboard Lib "EZTW32.dll"(hwndApp As Integer, wPixTypes As Integer) As Integer
		      Dim i As Integer
		      
		      i = TWAIN_AcquireToClipboard(0,0)
		      Dim clp As New Clipboard
		      If clp.PictureAvailable Then
		        pic = clp.Picture
		        If pic <> Nil Then
		          retVal = True
		        Else
		          reportError "Nil picture on clipboard" + thisModule
		        End If
		      Else
		        pic = Nil
		        reportError "No picture on clipboard" + thisModule
		      End If
		      clp.Close
		    End If
		  #EndIf
		  Return retVal
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function SelectSource() As Boolean
		  Dim retVal As Boolean
		  #If TargetWin32
		    Const thisModule = " - SelectSource"
		    If Self.Available Then
		      If system.IsFunctionAvailable("TWAIN_SelectImageSource","EZTW32.dll") Then
		        Soft Declare Function TWAIN_SelectImageSource Lib "EZTW32.dll"(x As Integer) As Integer
		        If TWAIN_SelectImageSource(0) = 1 Then
		          retVal = True
		        End If
		        reportError "TWAIN_SelectImageSource failed" + thisModule
		      End If
		    End If
		  #EndIf
		  Return retVal
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function AcquireNative() As Boolean
		  Dim retVal As Boolean
		  Const thisModule = " - AcquireNative"
		  #if TargetWin32
		    if self.Available Then
		      const GDI_ERROR = &hFFFF
		      soft Declare Function SelectPalette Lib "gdi32" (hdc As Integer, hPalette As Integer, bForceBackground As Integer) As Integer
		      soft Declare Function RealizePalette Lib "gdi32" (hdc As Integer) As Integer
		      soft Declare Function GlobalLock Lib "kernel32" (hMem As Integer) As Integer
		      
		      soft Declare Function TWAIN_DibDepth Lib "EZTW32.dll"(hdib As Integer) As Integer
		      soft Declare Function TWAIN_DibWidth Lib "EZTW32.dll"(hdib As Integer) As Integer
		      soft Declare Function TWAIN_DibHeight Lib "EZTW32.dll"(hdib As Integer) As Integer
		      //Declare Function TWAIN_DibNumColors Lib "EZTW32.dll"(hdib As Integer) As Integer
		      Soft Declare Function TWAIN_AcquireNative Lib "EZTW32.dll"(hwndApp As Integer, wPixTypes As Integer) As Integer
		      Soft Declare Sub TWAIN_FreeNative Lib "EZTW32.dll"(hDib As Integer)
		      soft Declare Function TWAIN_CreateDibPalette Lib "EZTW32.dll"(hDib As Integer) As Integer
		      Soft Declare Sub TWAIN_DrawDibToDC Lib "EZTW32.dll"(hdc As Integer,_
		      dx As Integer,dy As Integer,w As Integer,h As Integer,hdib As Integer, sx As Integer,sy As Integer)
		      
		      Dim gMem As Integer
		      Dim DibHandle As Integer
		      Dim hPall As Integer
		      
		      Dim dpth As Integer
		      Dim w As Integer
		      Dim h As Integer
		      
		      gMem = TWAIN_AcquireNative(0,0)
		      
		      DibHandle = GlobalLock(gMem)
		      if DibHandle = 0 Then
		        reportError "GlobalLock failed"
		      Else
		        dpth = TWAIN_DibDepth(DibHandle)
		        w = TWAIN_DibWidth(DibHandle)
		        h = TWAIN_DibHeight(DibHandle)
		        
		        pic = New Picture(w,h,dpth)
		        Dim g As Graphics = pic.Graphics
		        
		        hPall = TWAIN_CreateDibPalette(DibHandle)
		        '
		        Dim hdc as Integer
		        '
		        if SelectPalette(g.Handle( Graphics.HandleTypeHDC ),hPall,0) = 0 Then
		          reportError "SelectPalette failed" + thisModule
		        Else
		          if RealizePalette(g.Handle( Graphics.HandleTypeHDC )) = GDI_ERROR Then
		            reportError "RealizePalette failed" + thisModule
		          Else
		            TWAIN_DrawDibToDC(g.Handle( Graphics.HandleTypeHDC ),0,0,w,h,DibHandle,0,0)
		            TWAIN_FreeNative(DibHandle) //This calls GlobalFree
		            retVal = True // Assume success if we get here
		          end if
		        end if
		      end if
		    end if
		  #endif
		  Return retVal
		  
		End Function
	#tag EndMethod

	#tag Method, Flags = &h21
		Private Sub reportError(txt As String)
		  dim d as new Date
		  self.lastError = txt + EndOfLine + d.SQLDateTime
		End Sub
	#tag EndMethod


	#tag Note, Name = About
		This class was written by Steve Garman 
		http://rb.sgarman.net/sjgeztwain/
		
		It uses the Public Domain Windows dll EZTW32.dll by Dosadi
		available from http://www.dosadi.com/eztwain1.htm
		in REALbasic 
		
		This class requires EZTW32.dll to be either in the same folder
		as the app executable or to be in the Windows path
		
		%windir%/system32 is a good choice if looking for a folder
		that can be reasonably expected to be in the path.
	#tag EndNote

	#tag Note, Name = Warning
		There are many limitations to this class.
		
		One of them is that it may lock your application up if the user
		asks it to acquire when their TWAIN device is unplugged
		
		This depends on the driver for your particular scanner/camera etc.
	#tag EndNote

	#tag Note, Name = Usage
		  EZTW32.dll must be available in the Path or in the same folder as the .exe
		  (see About note)
		
		SelectSource Method
		  Only needs to be called if the user wishes to change the default TWAIN source
		  Displays the standard Select dialog
		  (Works by calling TWAIN_SelectImageSource)
		
		All Acquire functions
		  Call the currently selected source's dialog
		  Attempt to populate the class's public .pic property with a picture
		  Return True on success, False on falure.
		  Offer the reason for failure as a string in the public .lastError property
		
		AcquireNative Method
		  Populates the .pic picture directly with no intervening steps
		  (Works by calling TWAIN_AcquireNative)
		
		AcquireToClipboard Method
		  Captures the image to the system clipboard so it can be pasted into external applications like Pain
		  Also populates .pic from the clipboard
		  (Works by calling TWAIN_AcquireToClipboard)
		
		AcquireToFile Method
		  Takes an optional parameter which is a FolderItem pointing to the bmp file to be created.
		  Captures the image to a .bmp file
		  Offers a public property .fItem as a FolderItem pointing to the file created.s
		  Also populates .pic using fItem.OpenAsPicture
		  (Works by calling TWAIN_AcquireToFilename)
	#tag EndNote


	#tag Property, Flags = &h0
		Available As Boolean
	#tag EndProperty

	#tag Property, Flags = &h0
		EZTwainVersion As String
	#tag EndProperty

	#tag Property, Flags = &h0
		fItem As FolderItem
	#tag EndProperty

	#tag Property, Flags = &h0
		pic As Picture
	#tag EndProperty

	#tag Property, Flags = &h0
		lastError As String
	#tag EndProperty

	#tag ComputedProperty, Flags = &h0
		#tag Getter
			Get
			Return "sjgEZTwain for RB2006+ version 1.0.1"
			End Get
		#tag EndGetter
		classVersion As String
	#tag EndComputedProperty


	#tag ViewBehavior
		#tag ViewProperty
			Name="Name"
			Visible=true
			Group="ID"
			InheritedFrom="Object"
		#tag EndViewProperty
		#tag ViewProperty
			Name="Index"
			Visible=true
			Group="ID"
			InitialValue="2147483648"
			InheritedFrom="Object"
		#tag EndViewProperty
		#tag ViewProperty
			Name="Super"
			Visible=true
			Group="ID"
			InheritedFrom="Object"
		#tag EndViewProperty
		#tag ViewProperty
			Name="Left"
			Visible=true
			Group="Position"
			InitialValue="0"
			InheritedFrom="Object"
		#tag EndViewProperty
		#tag ViewProperty
			Name="Top"
			Visible=true
			Group="Position"
			InitialValue="0"
			InheritedFrom="Object"
		#tag EndViewProperty
		#tag ViewProperty
			Name="Available"
			Group="Behavior"
			InitialValue="0"
			Type="Boolean"
		#tag EndViewProperty
		#tag ViewProperty
			Name="EZTwainVersion"
			Group="Behavior"
			Type="String"
			EditorType="MultiLineEditor"
		#tag EndViewProperty
		#tag ViewProperty
			Name="pic"
			Group="Behavior"
			InitialValue="0"
			Type="Picture"
		#tag EndViewProperty
		#tag ViewProperty
			Name="lastError"
			Group="Behavior"
			Type="String"
			EditorType="MultiLineEditor"
		#tag EndViewProperty
		#tag ViewProperty
			Name="classVersion"
			Group="Behavior"
			Type="String"
			EditorType="MultiLineEditor"
		#tag EndViewProperty
	#tag EndViewBehavior
End Class
#tag EndClass
